package com.study.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.study.exception.ServiceException;
import com.study.mapper.UserMapper;
import com.study.model.dto.ForgetPasswordSetNewPasswordDto;
import com.study.model.dto.ForgetPasswordValidateUserDto;
import com.study.model.dto.ForgetPasswordValidateVerifyCodeDto;
import com.study.model.dto.request.*;
import com.study.model.dto.response.UserInfoRespDto;
import com.study.model.entity.User;
import com.study.service.UserService;
import com.study.util.DateTimeUtil;
import com.study.util.SysConst;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private UserMapper userMapper;


    @Override
    public void userRegister(UserRegisterDto registerDto) {

        //验证码是否正确
        RBucket<String> rBucket = redissonClient.getBucket("sms:verify:" + registerDto.getPhone());
        if (!StringUtils.equals(registerDto.getVerifyCode(), rBucket.get())) {
            throw new ServiceException("验证码错误");
        } else {
            rBucket.delete();
        }

        //是否已经被注册
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("phone", registerDto.getPhone()));
        if (user != null) {
            throw new ServiceException("手机号码已经被注册");
        }

        //保存账号
        user = new User();
        user.setCreateTime(DateTimeUtil.getNowString());
        user.setNickName(registerDto.getPhone());
        user.setPhone(registerDto.getPhone());
        user.setStatus(User.STATUS_NORMAL);
        user.setPassword(registerDto.getPassword());

        log.info("账号{}注册成功", registerDto.getPhone());
        userMapper.insert(user);

    }

    @Override
    public User login(UserLoginDto loginDto) {
        //查询用户是否存在
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("phone", loginDto.getPhone()));
        if (user == null) {
            throw new ServiceException("账户或密码错误");
        }

        //查询密码是否正确，密文对比密文
        if (!StringUtils.equals(user.getPassword(), loginDto.getPassword())) {
            throw new ServiceException("账户或密码错误");
        }
        log.info("用户{}成功登录系统，设备为：{}", loginDto.getPhone(), loginDto.getDevice());
        return user;

    }

    @Override
    public String forgetValidateUser(ForgetPasswordValidateUserDto forgetPasswordValidateUserDto) {
        RBucket<String> rBucket = redissonClient.getBucket(SysConst.RedisPrefix.IMAGE_VERIFY_CODE + forgetPasswordValidateUserDto.getTokenId());
        if (!StringUtils.equalsIgnoreCase(forgetPasswordValidateUserDto.getVerifyCode(), rBucket.get())) {
            throw new ServiceException("验证码错误");
        } else {
            rBucket.delete();
        }
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("phone", forgetPasswordValidateUserDto.getPhone()));
        if (user == null) {
            throw new ServiceException("账号不存在");
        }

        String token = UUID.randomUUID().toString().replace("-", "");
        RBucket<String> sendVerifyCodeCache = redissonClient.getBucket(SysConst.RedisPrefix.FORGET_PASSWORD_SEND_VERIFY + token);
        sendVerifyCodeCache.set(user.getPhone(), 10, TimeUnit.MINUTES);
        return token;
    }

    @Override
    public void forgetValidateVerifyCode(ForgetPasswordValidateVerifyCodeDto forgetPasswordValidateVerifyCodeDto) {
        RBucket<String> rBucket = redissonClient.getBucket(SysConst.RedisPrefix.SEND_VERIFY_PHONE_MAP + forgetPasswordValidateVerifyCodeDto.getToken());
        if (!StringUtils.equalsIgnoreCase(forgetPasswordValidateVerifyCodeDto.getVerifyCode(), rBucket.get())) {
            throw new ServiceException("验证码错误");
        } else {
            rBucket.delete();
        }
    }

    @Override
    public void forgetSetNewPassword(ForgetPasswordSetNewPasswordDto forgetPasswordSetNewPasswordDto) {
        RBucket<String> rBucket = redissonClient.getBucket(SysConst.RedisPrefix.FORGET_PASSWORD_SEND_VERIFY + forgetPasswordSetNewPasswordDto.getToken());
        if (!rBucket.isExists()) {
            throw new ServiceException("验证码已过期，请重新获取");
        }
        String phone = rBucket.get();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("phone", phone));
        if (user == null) {
            throw new ServiceException("用户不存在");
        }
        rBucket.delete();
        user.setPassword(forgetPasswordSetNewPasswordDto.getPassword());
        userMapper.updateById(user);
        log.info("{}用户修改密码为{}", user.getId(), user.getPassword());
    }

    @Override
    public UserInfoRespDto getUserInfo(String userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new ServiceException("用户不存在");
        }
        UserInfoRespDto userInfoRespDto = new UserInfoRespDto();
        userInfoRespDto.setUserId(userId);
        userInfoRespDto.setNickName(user.getNickName());
        userInfoRespDto.setJoinDate(user.getCreateTime());
        userInfoRespDto.setJoinDays(DateTimeUtil.daysBetweenNow(user.getCreateTime()));
        userInfoRespDto.setUserStatus(user.getStatus());
        Integer tagCount = 0;
        Integer memoCount =0;

        log.info("获取到用户的信息{}", userInfoRespDto);
        return userInfoRespDto;
    }


    @Override
    public void changeNickNameAndPassword(UserSettingDto userSettingDto) {
        User user = userMapper.selectById(userSettingDto.getUserId());
        if (user == null) {
            throw new ServiceException("用户不存在");
        }
        if (StringUtils.isNoneEmpty(userSettingDto.getNickName())) {
            user.setNickName(userSettingDto.getNickName());
        }
        if (StringUtils.isNoneEmpty(userSettingDto.getNewPassword())) {
            if (!user.getPassword().equals(userSettingDto.getOldPassword())) {
                throw new ServiceException("旧密码输入错误");
            }
            user.setPassword(userSettingDto.getNewPassword());
        }
        userMapper.updateById(user);
        log.info("用户{}修改密码为{}", userSettingDto.getUserId(), userSettingDto.getNewPassword());
    }


}
